﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;

#if UNITY_EDITOR
using UnityEditor;
[CustomEditor(typeof(HairGen))]
public class HairsGenEditor : E_ShowButtons<HairGen> { }
#endif

public partial class HairGen : MonoSingleton<HairGen>, IFind
{
    void Start()
    {
        hairs = new List<Hair>();
        snapToSurf = true;
        mirror = false;
        mirror_Changed(mirror);
        trail.time = Mathf.Infinity;

        curveBoneLength = Curve2.T0V1_T1V1;
        curveBoneLength.time1D = true;
        curveWidth = Curve2.T0V1_T05V1_T1V0;
        //curveWidth.time1D = true;
        curveThickness = Curve2.T0V1_T05V1_T1V0;
        //curveThickness.time1D = true;

        curveCrsSecFront = Curve2.T0V1_T05V1_T1V0;
        curveCrsSecBack = Curve2.T0V0_T1V0;

        InputEvents.I.svMouseDown2D = SVMouseDown2D;
        InputEvents.I.svMouseUp2D = SVMouseUp2D;
        InputEvents.I.svMouseDownMove2D = SVMouseDownMove2D;

        Selector.I.onClick += OnClick;
        Selector.I.onSelectionChanged += OnSelectionChanged;
    }
    void OnSelectionChanged()
    {
        if (Selector.current != null)
        {
            SetDataFromHair(hairCurr);
            if (hairCurr != null && hairCurr.curveData.relaHairs.NotEmpty() && SetToPivot)
            {
                pivot.position = hairCurr.curveData.pose[0].vector + Vector3.forward * radius;
            }
            _poseScale = poseScale = 1;
        }
        OnClickHair();
    }
    void OnClickHair()
    {
        //timer = 0;
        //trigger = true;
        foreach (var hair in hairs)
        {
            if(hair.renderData!=null &&hair.renderData.matName.NotEmpty())
            {
                hair.GetComponent<SkinnedMeshRenderer>().sharedMaterial =
                    mats.GetByName(hair.renderData.matName);
            }
            else hair.GetComponent<SkinnedMeshRenderer>().sharedMaterial = hairMat;
        }
        if (Selector.current == null) return;
        var smr = Selector.current.GetComponent<SkinnedMeshRenderer>();

        var hairMatSel = Instantiate(smr.sharedMaterial);
        hairMatSel.SetColor("_Outline_Color", colorHairSel);
        hairMatSel.SetFloat("_Outline_Width", 3);
        smr.sharedMaterial = hairMatSel;

        if (UICurve.I.gameObject.activeSelf == true)
        {
            var idx = curveEdit_idx;
            if (idx == 0)
            {
                UICurve.I.mirror = false;
                UICurve.I.Curve = curveWidth;
            }
            else if (idx == 1)
            {
                UICurve.I.mirror = false;
                UICurve.I.Curve = curveThickness;
            }
            else if (idx == 2)
            {
                UICurve.I.mirror = true;
                UICurve.I.Curve = curveCrsSecFront.Before(0.5f);
            }
        }
    }
    [ContextMenu("PrintHairs")]
    void PrintHairs()
    {
        foreach (var hair in hairs)
        {
            Debug.Log(hair.name);
        }
    }
    //[ShowToggle("")]
    public bool SetToPivot = true;
    [Range(0, 2)]
    public float poseScale;
    float _poseScale;

    int _circleCount;
    float _hairWidth;
    float _hairThickness;
    float _length;
    void Update()
    {
        // 有时读取数据还是会丢失部分RelasHair，比如最后一个
        // （完成）使用 Kajiya-Kay 着色
        // （完成）Relas 每帧更新
        // （完成）长度、宽度改变自动重新生成，并且更新关联头发
        // （完成）实时调整circle数量，细分Pose曲线
        // （完成）修改 SnapIK 算法，指定父子关系
        // （完成）uv归一化
        // Duplicate时改名数字
        // Apply时保持RenderData

        if (_hairWidth != hairWidth || _hairThickness != hairThickness || _length != length)
        {
            _hairWidth = hairWidth;
            _hairThickness = hairThickness;
            _length = length;
            ApplyGenData_Curr();            
        }
        if (_circleCount != circleCount)
        {
            _circleCount = circleCount;
            GenerateCircle();
        }

        Curve3.accuracy = curve3Accuracy;
        list = new List<Hair>();//hairs to process
        foreach (var hair in hairs)
        {
            if (Selector.current == hair.transform)
            {
                list.Add(hair);
                var mir = hair.curveData.pair;
                if (mir != null)
                {
                    list.Add(mir);
                    var smr = mir.GetComponent<SkinnedMeshRenderer>();
                    smr.localBounds = hair.GetComponent<SkinnedMeshRenderer>().localBounds.MirrorX();
                }
            }
        }
        if (_poseScale != poseScale)
        {
            foreach (var hair in list)
            {
                hair.curveData.pose.Scale(Vector3.one * 1f / _poseScale * poseScale);
            }
            _poseScale = poseScale;
        }
        foreach (var h in list)
        {
            h.curveData.SnapBonesToCurve();
            h.UpdateMeshCol();
            var rls = h.curveData.relaHairs;
            if (rls.NotEmpty())
            {
                pivot.rotation = Quaternion.AngleAxis(h.curveData.pivotEuler.x, Vector3.right);

                angle = 360f / (rls.Count + 1);
                if (SetToPivot) h.curveData.pose.SetRootPos(pivot.position - Vector3.forward * radius);
                int i = 0;
                foreach (var rl in rls)
                {
                    rl.curveData.pose.SetCurve(h.curveData.pose);

                    rl.curveData.pose.AddVector(-pivot.position);
                    var rot = Quaternion.AngleAxis(angle * ++i, pivot.up);
                    rl.curveData.pose.Rotate(rot);
                    rl.curveData.pose.AddVector(pivot.position);

                    rl.curveData.pose.Scale(h.curveData.circleScale);

                    rl.curveData.SnapBonesToCurve();
                    rl.UpdateMeshCol();
                }
            }
        }
        if (Events.KeyDown(KeyCode.Tab))
        {
            editCurve = !editCurve;
            editCurve_Changed(editCurve);
        }
        else if (Events.KeyDown(KeyCode.F))
        {
            mirror = !mirror;
        }
        else if (Events.KeyDown(KeyCode.B))
        {
            showXBoard = !showXBoard;
            showXBoard_Changed(showXBoard);
        }
        else if (Events.KeyDown(KeyCode.P))
        {
            snapToSurf = !snapToSurf;
        }
        else if (Events.KeyDown(KeyCode.L))
        {
            append = !append;
        }
        else if (Events.KeyDown(KeyCode.A))
        {
            Selector.I.UnSelectAll();
        }
        else if (Events.KeyDown(KeyCode.M))
        {
            AddMirrorHair();
        }
        else if (Events.KeyDown(KeyCode.X))
        {
            DeleteHair();
        }
        else if (Events.KeyDown(KeyCode.D))
        {
            UICurve.I.ToggleActive();
        }
        else if (Events.KeyDown_Enter)
        {
            ApplyGenData_Curr();
        }
        else if (Events.KeyDown(KeyCode.Q))
        {
            // 这里使用了短路，idx不同时不会Toggle隐藏曲线界面
            if (curveEdit_idx != 0 || UICurve.I.ToggleActive()) CurveEdit(0);
        }
        else if (Events.KeyDown(KeyCode.W))
        {
            if (curveEdit_idx != 1 || UICurve.I.ToggleActive()) CurveEdit(1);
        }
        else if (Events.KeyDown(KeyCode.E))
        {
            if (curveEdit_idx != 2 || UICurve.I.ToggleActive()) CurveEdit(2);
        }
    }
}
